#pragma once
#include "zMatrixBase.hpp"

namespace zzz{
//func(mat,mat)
#define CONSTANT_EXPRESSIONM(name,func) \
template<typename T,class Major>\
class zFunction##name##ExpressionM : public zMatrixBaseR<T,Major>\
{\
public:\
  explicit zFunction##name##ExpressionM(const zMatrixBaseR<T,Major>& mat1, const zMatrixBaseR<T,Major>& mat2)\
  :zMatrixBaseR<T,Major>(mat1.rows_,mat1.cols_),Mat1_(mat1),Mat2_(mat2){assert(Mat1_.rows_==Mat2_.rows_ && Mat1_.cols_==Mat2_.cols_);}\
  using zMatrixBaseR<T,Major>::operator(); \
  const T operator()(zuint r, zuint c) const\
  {\
    CheckRange(r, c); \
    return func(Mat1_(r,c), Mat2_(r,c)); \
  }\
private:\
  const zMatrixBaseR<T,Major> &Mat1_, &Mat2_; \
}; \

CONSTANT_EXPRESSIONM(Pow,Pow<T>)
template<typename T,class Major>
const zFunctionPowExpressionM<T,Major> operator^(const zMatrixBaseR<T,Major> &mat1, const zMatrixBaseR<T,Major> &mat2)
{return zFunctionPowExpressionM<T,Major>(mat1,mat2);};

}
